#ifndef TAGGER_H_
#define TAGGER_H_
#include <vector>
#include <string>
#include "feature.h"
const int X_ = 200;
const int Y_ = 50;
namespace MRFPP
{
	class FeatureIndex;
	class Tagger
	{
		protected:
			int feature_id_;// the node we have so far
			FeatureIndex* feature_index_;
			std::vector <int> result; // decode
			std::vector <int> answer;//golden
			double Z_;
			//std::vector<std::vector <const char*>> x_;
			size_t xsize_;
			size_t ysize_;
			double forwardMatrix[X_][Y_];
			double backwardMatrix[X_][Y_];
			double nodePotential[X_][Y_];
			double edgePotential[X_][Y_][Y_];
			double edgePosterior[X_][Y_];
			double nodePosterior[X_][Y_];
			double bestCost[X_][Y_];
			int pos[X_][Y_];
			std::vector <double>& alpha_;//weight
			std::vector <std::string> x_; // observe data
		public:
			Tagger(std::vector <double>& alpha):alpha_(alpha){};
			Tagger();
			virtual~Tagger() {}
			virtual double gradient(double *) = 0;
			virtual void setTag(std::vector <int>&) = 0;
			void fillNodePotential(size_t, size_t, std::vector <int>&);
			void fillEdgePotential(size_t, size_t, size_t, std::vector <int>&);
			void updateNodePotential(size_t, std::vector <int>&);
			void updateEdgePotential(size_t, size_t, std::vector <int>&);
			void open(FeatureIndex*, int, bool);
			int viterbi(bool);//return the right #
			void forwardbackward();
			size_t get_xsize() const{return xsize_;}
			//void update();// for voted peceptron
			void set_alpha(std::vector<double>& alpha)
			{
				alpha_ = alpha;
			}
			void set_feature_id(int id)
			{
				feature_id_ = id;
			}
			int feature_id() const
			{
				return feature_id_;
			}
			size_t size()
			{
				return xsize_;
			}
			size_t xsize()
			{
				return xsize_;
			}
			size_t ysize()
			{
				return ysize_;
			}

	};
}
#endif
